package cn.wolfcode.intercepter;


import cn.wolfcode.domain.Employee;
import cn.wolfcode.service.PermissionService;
import cn.wolfcode.util.RequirePermission;
import cn.wolfcode.util.UserContext;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

//权限拦截器

/**
 *权限拦截器
 * 当用户发送请求时，先经过登录拦截器，在通过权限拦截器（用户请求其他非登录页面时，说明已经登录）
 * 通过session拿到用户的相关信息，判断是否为超级管理员，如果是，则直接放行
 * 通过员工id的sql拿到该用户的所有的权限表达式permissionList
 *  传入employee.id (employee_role,role_permission 拿到 permissionID  在跟 permission比)
 * 通过handler拿到页面请求的映射方法，根据RequestMapping注解，拿到请求路径，跟permissionList对比，
 *        如果包含（有权限），放行
 *           否则，拦截，跳转到其他页面
 */
@Component
public class PermissionIntercepter implements HandlerInterceptor {


    /**
     * 因为这个里面有handleMapping处理器映射器，会去找addInterceptors方法去添加permissionIntercepter拦截器，
     * 此时PermissionService为空，导致了PermissionIntercepter为空
     * 因此我们可以配置延迟加载，当调用的时候在用它，其他情况不用理他调用它
     */
    @Lazy
    @Autowired
    private PermissionService permissionService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //拿到存储了用户的session信息
//        Employee employee = (Employee)request.getSession().getAttribute("USER_IN_SESSION");
        Employee employee = UserContext.getCurrentEmployee();



        //拿到用户拥有的所有权限
//        List<String> list = permissionService.selecByEmployeeId(employee.getId());
//        List<String> list = (List<String>)request.getSession().getAttribute("EXPERSSION_IN_SESSION");
        List<String> list = UserContext.getCurrentExpermission();
        //根据handle拿到用户请求的方法，通过方法拿到注解，通过注解拿到对应的表达式
        //通过handle拿到对应的请求映射方法

        // request.getRequestDispatcher("src/main/webapp/WEB-INF/views/common/nopermission.ftl");
        //该请求经过tomcat的defaultServlet处理吗，经过DefaultServletHttpRequtHandler这个处理静态资源的对象处理
        //所以就不能强转为方法，需要进行判断放行
         if (!(handler instanceof HandlerMethod)){
             return true;
         }


        HandlerMethod handlerMethod = (HandlerMethod) handler;
        //通过方法拿到对应的注解

        RequirePermission annotation = handlerMethod.getMethodAnnotation(RequirePermission.class);
        if (annotation == null){  //如果访问的这个方法不需要权限，则直接放行
            return  true;
        }

        //当我们没贴权限注解时，经过这里也要进行判断，导致了空指针
        //所以应该先判断是否有注解，在判断是否登录
        if (employee.isAdmin()){ //如果是超级管理员
            return  true; //直接发放行
        }

        //通过注解拿到对应的权限表达式
        String experssion = annotation.experssion();
        //判断用户是否拥有这个权限
        if (list.contains(experssion)) { //如果不拥有，则跳转到对应的nopermission页面
            //由于请求转发和重定向，都不会被视图解析器解析
            //所以不被认为是ftlh，这样的话，里面使用的include标签也就没用了，样式也没用
            //因此，我们可以重定向使用请求，到controller。然后通过映射方法来帮我们跳转到对应的nopermission页面
            return true;   //由于没有权限，所以进行拦截

        }
//        request.getRequestDispatcher("src/main/webapp/WEB-INF/views/common/nopermission.ftl");
        //由于经过DefaultServlet进行处理，不会经过视图解析器，所以ftl没起作用
        //因此我们需要通过访问前端控制器来访问到ftl文件即可    （经过拦截器后，在经过前端控制器 ）
        response.sendRedirect("/permission/nopermission");
        return false;  //拦截
    }
}
